package com.saturday.web.translates.processor;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.saturday.common.util.SpringUtil;
import com.saturday.web.translates.annotaion.JsonDict;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
public class DictProcessor {
    public static Object jsonDict(Object data) {
        if (data instanceof List) {
            /*如果为返回列表场景则转换成list，逐个处理*/
            List list = (List) data;
            List resultList = new ArrayList();
            for (Object object : list) {
                JSONObject jsonObject = jsonObjectDict(object);
                resultList.add(jsonObject);
            }
            return resultList;
        } else if (data instanceof Set) {
            /*如果为返回列表场景则转换成list，逐个处理*/
            Set list = (Set) data;
            List resultList = new ArrayList();
            for (Object object : list) {
                JSONObject jsonObject = jsonObjectDict(object);
                resultList.add(jsonObject);
            }
            return resultList;
        } else if (data instanceof PageInfo) {
            PageInfo page = (PageInfo) data;
            List list = page.getList();
            List resultList = new ArrayList();
            for (Object object : list) {
                JSONObject jsonObject = jsonObjectDict(object);
                resultList.add(jsonObject);
            }
            page.setList(resultList);
            return page;
        } else if (data != null && !ClassUtil.isBasicType(data.getClass()) && !ClassUtil.isSimpleTypeOrArray(data.getClass())) {
            /*如果为普通对象返回场景，则逐个处理*/
            JSONObject jsonObject = jsonObjectDict(data);
            return jsonObject;
        }
        return data;
    }

    private static JSONObject jsonObjectDict(Object data) {
        if (ObjectUtil.isNotNull(data)) {
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data));
            Field[] fields = data.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (!ClassUtil.isBasicType(field.getType()) && !ClassUtil.isSimpleTypeOrArray(field.getType())) {
                    //如果非基础类型并且不为基础包装类型
                    convertChildJsonObject(data, jsonObject, field);
                } else {
                    JsonDict jsonDict = field.getAnnotation(JsonDict.class);
                    if (null != jsonDict && StringUtils.isNotBlank(jsonObject.getString(field.getName()))) {
                        String label = "";
                        try {
                            // TODO 待实现字典查询方法
                            Method selectLabal = ReflectionUtils.findMethod(SpringUtil.getBean("").getClass(), "", String.class, String.class);
                            label = (String) ReflectionUtils.invokeMethod(selectLabal, SpringUtil.getBean(""), jsonDict.dictType(), jsonObject.getString(field.getName()));
                        } catch (Exception e) {
                            log.error("反射字典方法异常");
                        }

                        JSONObject dictJson = new JSONObject();
                        dictJson.put("value", jsonObject.getString(field.getName()));
                        dictJson.put("label", label);
                        jsonObject.put(field.getName(), dictJson);
                    }
                }
            }
            return jsonObject;
        }
        return null;
    }

    private static void convertChildJsonObject(Object data, JSONObject jsonObject, Field field) {
        String methodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
        try {
            Method getMethod = data.getClass().getDeclaredMethod(methodName, null);
            Object childData = getMethod.invoke(data, null);
            if (childData instanceof List) {
                List list = (List) childData;
                List resultList = new ArrayList();
                for (Object object : list) {
                    //如果列表里直接就是基础类型，则直接跳过
                    if (ClassUtil.isBasicType(object.getClass()) || object.getClass().equals(String.class)
                            || object.getClass().equals(BigDecimal.class)) {
                        resultList = list;
                        break;
                    }
                    JSONObject resultJson = jsonObjectDict(object);
                    resultList.add(resultJson);
                }
                jsonObject.put(field.getName(), resultList);
            } else if (childData instanceof Set) {
                Set set = (Set) childData;
                List resultList = new ArrayList();
                for (Object object : set) {
                    //如果列表里直接就是基础类型，则直接跳过
                    if (ClassUtil.isBasicType(object.getClass()) || object.getClass().equals(String.class)
                            || object.getClass().equals(BigDecimal.class)) {
                        resultList.addAll(set);
                        break;
                    }
                    JSONObject resultJson = jsonObjectDict(object);
                    resultList.add(resultJson);
                }
                jsonObject.put(field.getName(), resultList);
            } else {
                JSONObject childJson = jsonObjectDict(childData);
                jsonObject.put(field.getName(), childJson);
            }
        } catch (NoSuchMethodException e) {
            log.error("未能获取到get方法：{}", methodName);
        } catch (IllegalAccessException e) {
            log.error("get方法调用参数错误：{}", methodName);
        } catch (InvocationTargetException e) {
            log.error("get方法调用异常：{}", methodName);
        }
    }
}
